﻿/**********************************************************************
 * @file   OperatorsJunctionAuto.h
 * @brief  自动连接操作器
 * @author BaGuijun (baguijun@163.com)
 * @date   2024-11-18
 *********************************************************************/

#ifndef _OperatorsJunctionAuto_H
#define _OperatorsJunctionAuto_H

#include "OperatorsInterface/ParaWidgetInterfaceOperator.h"
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
#include "FITK_Kernel/FITKCore/FITKThreadTask.h"
#include "FITK_Component/FITKAcousticsModel/FITKAbstractJunction.h"

namespace Acoustics {
    class FITKAcousticsSEAModel;
    class FITKAbstractSEASubSys;
    class FITKAcousticsDiscModel;
}

namespace ModelOper
{
    /**
     * @brief  自动连接操作器
     * @author BaGuijun (baguijun@163.com)
     * @date   2024-11-18
     */
    class OperatorsJunctionAuto :public EventOper::ParaWidgetInterfaceOperator
    {
        friend class ThreadSEAJunctionAuto;
        Q_OBJECT;
    public:
        /**
         * @brief    Construct a new Operators Open object
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        explicit OperatorsJunctionAuto() = default;
        /**
         * @brief    Destroy the Operators Open object
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        virtual ~OperatorsJunctionAuto() = default;
        /**
         * @brief    执行界面操作
         * @return   true     执行成功
         * @return   false     执行失败
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        virtual bool execGUI() override;
        /**
         * @brief    执行读入操作
         * @return   true     执行成功
         * @return   false     执行失败
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        virtual bool execProfession() override;
    private slots:
        ;
        /**
         * @brief    线连接创建完成槽函数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-19
         */
        void slotJunLineCreateComplete();
        /**
         * @brief    面连接创建完成槽函数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-19
         */
        void slotJunAreaCreateComplete();
    private:
        static int _lineNum;
        static int _areaNum;
    };

    // 按钮注册相关操作
    Register2FITKOperatorRepo(actionAutoJunctions, OperatorsJunctionAuto);

    //-------------------------------------------------------------------------------------------------------
    /**
     * @brief  自动连接线程类
     * @author BaGuijun (baguijun@163.com)
     * @date   2024-11-18
     */
    class ThreadSEAJunctionAuto :public Core::FITKThreadTask
    {
        Q_OBJECT;
    public:
        ThreadSEAJunctionAuto(Acoustics::FITKAbstractJunction::JunctionType type);
        virtual ~ThreadSEAJunctionAuto() = default;
        /**
         * @brief    线程执行函数
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        virtual void run() override;

    signals:
        ;
        /**
         * @brief    创建完成信号
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-19
         */
        void sigCreateComplete();
    private:
        /**
         * @brief    线自动连接
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        void junctionLineAuto();
        /**
         * @brief    面自动连接
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-18
         */
        void junctionAreaAuto();
        /**
         * @brief    获取所有子系统的边
         * @param[i] allShellBoundary      所有边
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-20
         */
        void junctionLineGetAllShellBoundary(QHash<Acoustics::FITKAbstractSEASubSys*, QList<int>>& allShellBoundary);
        /**
         * @brief    获取板边界的有序对
         * @param[i] edges             板边界
         * @return   QList<int>        计算后的有序对
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-19
         */
        QList<int> junctionLineShellBoundary(QList<QPair<int, int>>& edges);
        /**
         * @brief    重排序
         * @param[i] nodeIdList 
         * @param[i] failSub     失败的子系统
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-20
         */
        Acoustics::FITKAbstractSEASubSys* junctionLineIdReRanking(QList<int>& nodeIdList, bool& isSuccess);

        void dfs(int node, const QList<QPair<int, int>>& edges, QList<int>& result, QHash<int, bool>& visited);
        /**
         * @brief    对重排序失败的边进行处理
         * @param[i] subShellList           失败边所在子系统的边
         * @param[i] failLine               失败的边
         * @return   QList<QList<int>>      处理后的有效边
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-20
         */
        QList<QList<int>> junctionLineReRankFailProcess(const QList<int>& subShellList, const QList<int>& failLine);
        /**
         * @brief    
         * @param[i] points 
         * @return   bool
         * @author   BaGuijun (baguijun@163.com)
         * @date     2024-11-29
         */
        bool junctionLineFind(QList<int> points);
    private:
        /**
         * @brief  自动连接类型
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-11-18
         */
        Acoustics::FITKAbstractJunction::JunctionType _type = Acoustics::FITKAbstractJunction::JunctionType::NoneJunction;
        /**
         * @brief  离散模型
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-11-18
         */
        Acoustics::FITKAcousticsDiscModel* _DiscModel = nullptr;
        /**
         * @brief  SEA模型
         * @author BaGuijun (baguijun@163.com)
         * @date   2024-11-12
         */
        Acoustics::FITKAcousticsSEAModel* _SEAModel = nullptr;
    };
}

#endif